package com.mao.wx.demo.api;

import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.mao.wx.demo.constant.WxMessageConstant;
import com.mao.wx.demo.model.message.WxConfirmRequest;
import com.mao.wx.demo.model.message.WxImageMessage;
import com.mao.wx.demo.model.message.WxImageResponse;
import com.mao.wx.demo.model.message.WxTextMessage;
import com.mao.wx.demo.model.message.WxTextResponse;
import com.mao.wx.demo.model.message.WxVedioMessage;
import com.mao.wx.demo.model.message.WxVedioResponse;
import com.mao.wx.demo.model.message.WxVoiceMessage;
import com.mao.wx.demo.model.message.WxVoiceResponse;
import com.mao.wx.demo.util.WxMessageUtil;

@Controller
@RequestMapping(value="/wx")
public class WxGenericApi {

	@Autowired(required = true)
	@Qualifier("wxMessageUtil")
	private WxMessageUtil wxMessageUtil;

	/**
	 * 用于第一次与微信平台配置连接
	 * @param request
	 * @param resp
	 * @throws Exception
	 */
	@RequestMapping(value="/",method=RequestMethod.GET)
	public void wxConfirm(@Valid WxConfirmRequest request, HttpServletResponse resp) throws Exception {
		resp.setCharacterEncoding("utf-8");
		PrintWriter writer = resp.getWriter();
		try {
			if (request == null) {
				writer.write("Bad request!");
			} else {
				String signature = wxMessageUtil.getConfirmSignature(request);
				if (signature != null && signature.equals(request.getSignature())) {
					writer.write(request.getEchostr());
				} else {
					writer.write("Wrong connection");
				}
			}
		} finally {
			writer.flush();
			writer.close();
		}

	}

	/**
	 * 接受微信后台转发的消息入口API
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value="/",method=RequestMethod.POST)
	public void wxDoMessage(HttpServletRequest request,HttpServletResponse response) throws Exception{
		request.setCharacterEncoding("UTF-8");
		try {
			Map<String,String> xmlMap=wxMessageUtil.parseXmlToMap(request);
			Map<String,Object> objMap=wxMessageUtil.parseMapToObj(xmlMap);
			doMessageDispathcer(objMap, response);
		} catch (Exception e) {
			sendErrorMsg(response, "succsess");
			e.printStackTrace();
			throw e;
		}finally{
			
		}
	}
	
	/**
	 * 根据解析的消息类型，转发到对应的处理模块
	 * @param objMap
	 * @param response
	 * @throws Exception
	 */
	private void doMessageDispathcer(Map<String,Object> objMap,HttpServletResponse response) throws Exception{
		String type=(String) objMap.get("MsgType");
		if(type.equals(WxMessageConstant.XML_MSG_TEXT)){
			WxTextMessage requestMsg=(WxTextMessage) objMap.get("RequestMsg");
			WxTextResponse responseMsg=(WxTextResponse) objMap.get("ResponseMsg");
			doTextResponse(requestMsg, responseMsg, response);
		}else if(type.equals(WxMessageConstant.XML_MSG_IMAGE)){
			WxImageMessage wxImageMessage=(WxImageMessage) objMap.get("RequestMsg");
			WxImageResponse wxImageReponse=(WxImageResponse) objMap.get("ResponseMsg");
			doImageResponse(wxImageMessage, wxImageReponse, response);
		}else if(type.equals(WxMessageConstant.XML_MSG_VOICE)){
			WxVoiceMessage wxVoiceMessage=(WxVoiceMessage) objMap.get("RequestMsg");
			WxVoiceResponse wxVoiceReponse=(WxVoiceResponse) objMap.get("ResponseMsg");
			doVoiceResponse(wxVoiceMessage, wxVoiceReponse, response);
		}else if(type.equals(WxMessageConstant.XML_MSG_VIDEO)){
			WxVedioMessage wxVedioMessage=(WxVedioMessage) objMap.get("RequestMsg");
			WxVedioResponse wxVedioResponse=(WxVedioResponse) objMap.get("ResponseMsg");
			doVideoResponse(wxVedioMessage, wxVedioResponse, response);
		}
	}
	
	private void doVideoResponse(WxVedioMessage requstMsg,WxVedioResponse responseMsg,HttpServletResponse response) throws Exception{
		System.out.println("收到视频消息:"+requstMsg.getMediaId()+" thumbMediaId="+requstMsg.getThumbMediaId());
		responseMsg.getWxVedio().setDescription("猫片");
		responseMsg.getWxVedio().setMediaId("爽");
		responseMsg.getWxVedio().setTitle("猫的片");
		String xml=wxMessageUtil.getXmlResponse(responseMsg, WxVedioResponse.class);
		sendXmlMsg(xml, response);
	}

	private void doTextResponse(WxTextMessage requestMsg,WxTextResponse responseMsg,HttpServletResponse response) throws Exception{
		String content=requestMsg.getContent();
		System.out.println("收到消息:"+content);
		responseMsg.setContent("回复:"+content);
		String xml=wxMessageUtil.getXmlResponse(responseMsg, WxTextResponse.class);
		sendXmlMsg(xml, response);
	}
	
	private void doImageResponse(WxImageMessage requestMsg,WxImageResponse responseMsg,HttpServletResponse response) throws Exception{
		System.out.println("接受图片消息: id="+requestMsg.getMediaId()+" picUrl="+requestMsg.getPicUrl());
		responseMsg.getWxImage().setMediaId(requestMsg.getMediaId());
		String xml=wxMessageUtil.getXmlResponse(responseMsg, WxImageResponse.class);
		sendXmlMsg(xml, response);
	}
	
	private void doVoiceResponse(WxVoiceMessage requestMsg,WxVoiceResponse responseMsg,HttpServletResponse response) throws Exception{
		System.out.println("接受语音消息: id="+requestMsg.getMediaId()+" picUrl="+requestMsg.getFormat());
		responseMsg.getWxVoice().setMediaId("语音1+1");
		String xml=wxMessageUtil.getXmlResponse(responseMsg, WxVoiceResponse.class);
		sendXmlMsg(xml, response);
	}

	/**
	 * 直接返回微信后台协议定义的TCP消息，并关闭Spring Handler Chain
	 * @param response
	 * @param msg
	 * @throws Exception
	 */
	private void sendErrorMsg(HttpServletResponse response , String msg) throws Exception{
		PrintWriter writer=response.getWriter();
		writer.write(msg);
		writer.flush();
		writer.close();
	}
	
	private void sendXmlMsg(String xml,HttpServletResponse response) throws Exception{
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer=response.getWriter();
		writer.print(xml);
		writer.flush();
		writer.close();
	}
}
